<template>
	<view class="sms-btn">
		<slot :disabled="isDisabled" :countdown="countdown" :btnText="btnText">
			<el-button
				class="msg-btn"
				type="primary"
				:disabled="isDisabled"
				:placeholder="t('获取验证码')"
			>
				{{ btnText }}
			</el-button>
		</slot>

		<cl-dialog
			v-model="captcha.visible"
			width="400px"
			:title="t('获取验证码')"
			:padding="40"
			border-radius="24rpx"
		>
			<div class="sms-popup">
				<view class="row">
					<el-input
						v-model="form.code"
						:placeholder="t('获取验证码')"
						:maxlength="4"
						:height="70"
						:clearable="false"
						:border="false"
						background-color="#f7f7f7"
					/>

					<img :src="captcha.img" mode="aspectFit" @click="getCaptcha" />
				</view>

				<view class="btn">
					<el-button
						type="primary"
						fill
						:disabled="!form.code"
						:loading="captcha.sending"
						:height="70"
						@click.stop="send"
					>
						{{ t('获取验证码') }}
					</el-button>
				</view>
			</div>
		</cl-dialog>
	</view>
</template>

<script lang="ts" setup>
import { computed, type PropType, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useCool } from '/@/cool';
import { ElMessage } from 'element-plus';
const { t } = useI18n();

const props = defineProps({
	phone: String,
	type: String,
	height: Number,
	fontSize: Number,
	size: String as PropType<'large' | 'default' | 'small'>,
	border: {
		type: Boolean,
		default: true
	},
	plain: Boolean
});

const emit = defineEmits(['success']);

const { service, refs, setRefs } = useCool();

// 验证码
const captcha = reactive({
	visible: false,
	loading: false,
	sending: false,
	img: ''
});

// 倒计时
const countdown = ref(0);

// 是否禁用
const isDisabled = computed(() => countdown.value > 0 || !props.phone);

// 按钮文案
const btnText = computed(() =>
	countdown.value > 0 ? t('*s后重新获取').replace('*', String(countdown.value)) : t('获取验证码')
);

// 表单
const form = reactive({
	code: '',
	captchaId: ''
});

// 开始倒计时
function startCountdown() {
	countdown.value = 60;

	function fn() {
		countdown.value--;

		if (countdown.value < 1) {
			clearInterval(timer);
		}
	}

	const timer = setInterval(fn, 1000);
	fn();
}

// 发送短信
async function send() {
	if (form.code) {
		captcha.sending = true;

		await service.user.login
			.smsCode({
				phone: props.phone,
				...form
			})
			.then(() => {
				ElMessage.success(t('获取验证码成功'));
				startCountdown();
				close();
				emit('success');
			})
			.catch(err => {
				ElMessage.error(err.message);
				getCaptcha();
			});

		captcha.sending = false;
	} else {
		ElMessage.success(t('请输入验证码'));
	}
}

// 获取图片验证码
async function getCaptcha() {
	clear();
	captcha.loading = true;

	await service.user.login
		.captcha({ type: 'png', color: '#2c3142', phone: props.phone })
		.then(res => {
			form.captchaId = res.captchaId;
			captcha.img = res.data;
		})
		.catch(err => {
			ElMessage.error(err.message);
		});

	captcha.loading = false;
}

// 打开
function open() {
	if (props.phone) {
		captcha.visible = true;
		getCaptcha();
	}
}

// 关闭
function close() {
	captcha.visible = false;
	clear();
}

// 清空
function clear() {
	form.code = '';
	form.captchaId = '';
}

defineExpose({
	open,
	send,
	getCaptcha,
	startCountdown
});
</script>

<style lang="scss" scoped>
.sms-popup {
	width: 100%;
	padding: 10px 20px;
	box-sizing: border-box;

	.row {
		display: flex;
		align-items: center;
		margin-bottom: 20px;

		img {
			height: 35px;
			width: 100px;
			flex-shrink: 0;
			margin-left: 20px;
		}
	}
	.btn {
		display: flex;
		justify-content: flex-end;
	}
}
</style>
